package org.activision.model;

import java.util.HashMap;

import org.activision.Engine;
import org.activision.task.Task;
import org.activision.model.npc.Npc;
import org.activision.model.player.Player;
import org.activision.net.codec.ConnectionHandler;
import org.activision.Constants;
import org.activision.util.EntityList;
import org.activision.util.Misc;
import org.activision.util.RSTile;
import org.activision.util.Serializer;

public class World {

    private static EntityList<Player> players;
    private static EntityList<Npc> npcs;
    private static HashMap<Integer, Long> ips;
    public static EntityList<Player> getPlayers() {
    	synchronized (players) {
        return players;
    	}
    }

    public World() {
    	players = new EntityList<Player>(Constants.MAX_AMT_OF_PLAYERS);
    	npcs = new EntityList<Npc>(Constants.MAX_AMT_OF_NPCS);
    	ips = new HashMap<Integer, Long>();
    	npcs.add(new Npc((short) 0, RSTile.createRSTile(3220, 3222, 0)));
    }

    public static void registerConnection(ConnectionHandler p) {
        if (players.add(p.getPlayer())) {
            p.getPlayer().LoadPlayer(p); 
        }
    }

    public static void unRegisterConnection(final ConnectionHandler p) {
        if (p.getPlayer() != null) {	
        	if(p.getPlayer().getCombat().getLastAttackedTime() != 0 && System.currentTimeMillis() - p.getPlayer().getCombat().getLastAttackedTime() < 10000) {
        		Engine.getEntityExecutor().scheduleAtFixedRate(new Task() {
        			@Override
        			public void run() {
        				if(p.getPlayer().getCombat().getLastAttackedTime() != 0 && System.currentTimeMillis() - p.getPlayer().getCombat().getLastAttackedTime() < 10000) 
        					return;
        		        Serializer.SaveAccount(p.getPlayer());
        		        p.getPlayer().setOnline(false);
        		        players.remove(p.getPlayer());
                    	for(Player p2 : players)
                            if (p2.getFriends().contains(Misc.formatPlayerNameForDisplay(p.getPlayer().getUsername())))
                                    p2.UpdateFriendStatus(Misc.formatPlayerNameForDisplay(p.getPlayer().getUsername()), (short) 0, false);
        		        this.stop();
        			}
        				
        		}, 0,  1000);
        	}else{
            Serializer.SaveAccount(p.getPlayer());
        	p.getPlayer().setOnline(false);
        	for(Player p2 : players)
                if (p2.getFriends().contains(Misc.formatPlayerNameForDisplay(p.getPlayer().getUsername())))
                        p2.UpdateFriendStatus(Misc.formatPlayerNameForDisplay(p.getPlayer().getUsername()), (short) 0, false);
            players.remove(p.getPlayer());
        	}
        }
    }

    public static boolean isOnline(String Username) {
        for (Player p : players)
            if (p.getUsername().equals(Username))
                if (p.isOnline())
                    return true;

        return false;
    }
    
    public static boolean isOnList(String Username) {
        for (Player p : players)
            if (p.getUsername().equals(Username))
                    return true;

        return false;
    }

    public static boolean isOnList(Player player) {
        return players.contains(player);
    }

	public static EntityList<Npc> getNpcs() {
		synchronized (npcs) {
		return npcs;
		}
	}

	public static HashMap<Integer, Long> getIps() {
		synchronized (ips) {
		return ips;
		}
	}

}
